﻿#include "tcpserverassistant.h"
#include "ui_tcpserverassistant.h"

#include <QIntValidator>
#include <QHostInfo>
#include "myserver.h"
#include <QMessageBox>
#include "mysocket.h"

#include "protocol/protocol.h"
#include "protocol/protocol_struct.h"
#include "app_struct.h"
#include "app_global.h"


#if _MSC_VER >=1600
#pragma execution_character_set("utf-8")
#endif


TcpServerAssistant::TcpServerAssistant(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::TcpServerAssistant)
{
    ui->setupUi(this);
    qDebug()<<"char size:"<<sizeof (char);
    m_tcpServer  = nullptr;
    m_serverHexSend = false;
    //信息收发文本框高度3：1
    ui->splitter->setStretchFactor(0, 3);
    ui->splitter->setStretchFactor(1, 1);
    //设置端口输入校验
    ui->lineEdit_serverLocalPort->setValidator(new QIntValidator(0,65535));
    //ip校验正则
    QRegExp regExpIP("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])[\\.]){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");
    //设置IP输入校验
    ui->lineEdit_serverLocalIp->setValidator(new QRegExpValidator(regExpIP ,ui->lineEdit_serverLocalIp));
    //显示本地ip
    QString localip = this->sockethelper->Get_LocalIp();

    ui->lineEdit_serverLocalIp->setText(localip);

    ui->lineEdit_serverLocalPort->setText("13800");

    qDebug()<<"UI线程ID:"<<QThread::currentThreadId();
}

TcpServerAssistant::~TcpServerAssistant()
{
    if(m_tcpServer!=nullptr)
    {
        m_tcpServer->close();
        delete m_tcpServer;
    }
    delete ui;
}


//服务器端收到消息显示
void TcpServerAssistant::on_add_serverMessage(QString message)
{
    ui->text_serverRec->append(message);//显示
    ui->text_serverRec->moveCursor(QTextCursor::End);
    QByteArray byte = message.toUtf8();
    getShowClientDeviceSys(&byte);
}

//点击TCP服务器发送
void TcpServerAssistant::on_btn_serverSend_clicked()
{
    if(m_tcpServer!=nullptr && !m_tcpServer->isListening())
    {
        QMessageBox::information(this,"提示","没有建立TCP连接");
        return;
    }
    if(ui->comboBox->count()==1)
    {
        QMessageBox::information(this,"提示","没有连接任何客户端");
        return;
    }

    QByteArray byteArray;
    QString data =ui->text_serverSend->toPlainText();
    //Hex发送
    if(ui->chk_serverSendHex->isChecked())
    {
        //hex字符串转字节
        if(!this->m_tcpServer->sockethelper->HexStringToByte(data,byteArray))
        {
            QMessageBox::information(this,"提示","输入的十六进制字符串有误，请重新输入");
            return;
        }
    }
    //普通字符串发送
    else
    {
        byteArray= data.toLocal8Bit();
    }

    int n=ui->comboBox->currentIndex();
    if(n==0)//发送给所有连接
    {
        for (int i=1;i<ui->comboBox->count();i++)
        {
            MySocket* mysocket = ui->comboBox->itemData(i).value<MySocket*>();
            if(mysocket !=nullptr)
            {
                emit mysocket->WriteMessage(byteArray);
            }
        }
    }
    //发送给选择的客户端
    else
    {
        MySocket* mysocket = ui->comboBox->itemData(n).value<MySocket*>();
        if(mysocket !=nullptr)
        {
            emit mysocket->WriteMessage(byteArray);
        }
    }
}

//点击tcp服务器监听/停止
void TcpServerAssistant::on_btn_serverListering_clicked()
{
    if(this->m_tcpServer==nullptr)//未连接
    {
        bool ok=false;
        //获取监听的端口号
        quint16 port=ui->lineEdit_serverLocalPort->text().toUShort(&ok);
        if(!ok)
        {
            QMessageBox::warning(this,"错误","端口设置有误，请重新输入");
            return;
        }
        //获取监听的Ip
        QHostAddress ip(ui->lineEdit_serverLocalIp->text());
        ip.toIPv4Address(&ok);
        if(!ok)
        {
            QMessageBox::warning(this,"错误","ip设置有误，请重新输入");
            return;
        }

        m_tcpServer=new MyServer(this);
        //设置线程
        m_tcpServer->SetThread(ui->spinBox_threadNum->value()-1);
        //监听
        bool islisten = m_tcpServer->listen(ip, port);
        if(!islisten)
        {
            QMessageBox::warning(this,"错误",m_tcpServer->errorString());
            m_tcpServer->close();
            m_tcpServer->deleteLater();//释放
            m_tcpServer=nullptr;
            return;
        }
        //更新ui
        ui->text_serverRec->append("开始监听"+QString("[%1：%2]\r\n").arg(ui->lineEdit_serverLocalIp->text()).arg(ui->lineEdit_serverLocalPort->text()));//消息框提示信息
        ui->btn_serverListering->setText("停止");
        ui->btn_serverListering->setIcon(QIcon(":/Resource/Img/stop36x36.png"));
        ui->lineEdit_serverLocalIp->setEnabled(false);
        ui->lineEdit_serverLocalPort->setEnabled(false);
        ui->spinBox_threadNum->setEnabled(false);
    }
    //停止server
    else
    {
        m_tcpServer->close();
        delete m_tcpServer;
        m_tcpServer=nullptr;
        //更新ui
        ui->text_serverRec->append("停止监听"+QString("[%1：%2]\r\n").arg(ui->lineEdit_serverLocalIp->text()).arg(ui->lineEdit_serverLocalPort->text()));//消息框提示信息
        ui->btn_serverListering->setText("监听");
        ui->btn_serverListering->setIcon(QIcon(":/Resource/Img/start36x36.png"));
        ui->lineEdit_serverLocalIp->setEnabled(true);
        ui->lineEdit_serverLocalPort->setEnabled(true);
        ui->spinBox_threadNum->setEnabled(true);
    }
}

//清除tcp服务器接收
void TcpServerAssistant::on_btn_serverClearRec_clicked()
{
    ui->text_serverRec->clear();
}

//清除tcp服务器发送
void TcpServerAssistant::on_btn_serverClearSend_clicked()
{
    ui->text_serverSend->clear();
}

//多线程，公开tcp服务器hex发送标志
void TcpServerAssistant::on_chk_ServerRecHex_clicked(bool checked)
{
    this->m_serverHexSend=checked;
}

void TcpServerAssistant::on_comboBox_currentIndexChanged(int index)
{
    ui->btn_serverCloseSocket->setEnabled(0==index?false:true);

}

void TcpServerAssistant::on_btn_serverCloseSocket_clicked()
{
    int index=ui->comboBox->currentIndex();
    if(index==0) return;
    //关闭socket
    emit m_tcpServer->list_information[index-1].mysocket->DeleteSocket();
}

void TcpServerAssistant::comboBox_remove()
{
    //清空combox
    while (ui->comboBox->count()>1)
    {
        ui->comboBox->removeItem(1);
    }
}

void TcpServerAssistant::comboBox_addItem(QString &atext , QVariant auserData)
{
    //增加combox
    ui->comboBox->addItem(atext,auserData);
}

void TcpServerAssistant::comboBox_removeItem(int index)
{
    //清空combox
    ui->comboBox->removeItem(index);
}


//显示客户端的系统信息
void TcpServerAssistant::getShowClientDeviceSys(QByteArray *msg)
{
    if (msg==NULL ) return;

    CONFIG_NET_REG_t* netfg;
    //数据长度判断
    if ( (uint32_t)sizeof(*netfg) <= (uint32_t)(msg->size()+17) )
    {
        //依据数据格式截取传输的数据
        dl_protocol_data_t net_data = {0};
        net_data.pcmd = (uint8_t *)msg;                     //接收缓存
        net_data.cmdlen = msg->size();                       //接收缓存长度
        net_data.pnet = 0;                                   //socket Id
        net_data.net_type = NET_TYPE_TCP;                     //socket 类

        int use_index = decode_dl(&net_data);

        //netfg = (CONFIG_NET_REG_t*)(msg->data()+17);
    }
    else
    {
        return;
    }

    memcpy(&System_Base_Param, netfg,sizeof(System_Base_Param) );

    //设置表格数据区内的所有单元格都不允许编辑
    ui->dev_tbl->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //自定义表格的尺寸和字体大小
    ui->dev_tbl->setFont(QFont("宋体",10));
    //设置表格的行数
    //ui->dev_tbl->setRowCount(10);
    int counts = ui->dev_tbl->rowCount();    //表格行
    //在表格第 row 行的位置插入一个空行。
    ui->dev_tbl->insertRow(0);
    int col = 0;
    //向表格指定位置添加单元格
    ui->dev_tbl->setItem(0, col++, new QTableWidgetItem(
                             QString::asprintf("%d", counts + 1 )));//序号
    ui->dev_tbl->setItem(0, col++, new QTableWidgetItem(
                             QString::asprintf("%d.%d.%d.%d:%d",
                              netfg->local.ip[0],
                              netfg->local.ip[1],
                              netfg->local.ip[2],
                              netfg->local.ip[3],
                              netfg->local.port)) );    //本地IP地址:端口
    ui->dev_tbl->setItem(0, col++, new QTableWidgetItem(
                             QString::asprintf("%d.%d.%d.%d:%d",
                            netfg->host.ip[0],
                            netfg->host.ip[1],
                            netfg->host.ip[2],
                            netfg->host.ip[3],
                            netfg->host.port)));  //上位机IP地址:端口
    ui->dev_tbl->setItem(0, col++, new QTableWidgetItem(
                             QString::asprintf("%d:%d:%d:%d",
                                            netfg->netmask[0],
                                            netfg->netmask[1],
                                            netfg->netmask[2],
                                            netfg->netmask[3])));//子网掩码

    ui->dev_tbl->setItem(0, col++, new QTableWidgetItem(
                             QString::asprintf("%d.%d.%d.%d",
                                            netfg->gateway[0],
                                            netfg->gateway[1],
                                            netfg->gateway[2],
                                            netfg->gateway[3]) ) ); //网关
    ui->dev_tbl->setItem(0, col++,new QTableWidgetItem(
                             QString::asprintf("%s",netfg->Device_ID) ) );//设备编号
    ui->dev_tbl->setItem(0, col++,  new QTableWidgetItem(
                             QString::asprintf("%d%d%d%d-%d%d%d%d",
                                            netfg->hwver[0],
                                            netfg->hwver[1],
                                            netfg->hwver[2],
                                            netfg->hwver[3],
                                            netfg->fwver[0],
                                            netfg->fwver[1],
                                            netfg->fwver[2],
                                            netfg->fwver[3]) ) );//版本号

}

/* 发送获取客户端的系统消息指令 */
void TcpServerAssistant::getSendClientSysCmd(MySocket* mysocket)
{
    int size = sizeof(cmd_t) + 20;
    QByteArray byteArray;
    byteArray.resize( sizeof(cmd_t) + 20);
    uint8_t* buf = new uint8_t[size];
    uint8_t* cmd = buf + 8;
    *cmd = CMD_GET;                              //获取功能指令
    uint32_t* pos = (uint32_t*)(cmd + 1);
    *pos = 0x080F9800;                           //地址
    uint32_t* len = pos + 1;
    *len = sizeof(CONFIG_SYSTEM_BASE);           //长度
    int cmdlen = 0;
    //打包数据
    encode_dl(buf, &cmdlen, buf + 8, size - 14);

    memcpy(byteArray.data(),buf,size);

    if(mysocket !=nullptr)
    {
        emit mysocket->WriteMessage(byteArray);
    }

    delete[]buf;
}



void TcpServerAssistant::on_find_bt_clicked()
{
    //发送给所有连接
    for (int i=1;i<ui->comboBox->count();i++)
    {
        MySocket* mysocket = ui->comboBox->itemData(i).value<MySocket*>();
        if(mysocket !=nullptr)
        {
            getSendClientSysCmd(mysocket);
        }
    }
}

